all repos — caroster @ c8aecf6e3de9336a00bdf30da7bcfde3f49a9cc2

[Octree] Group carpool to your event https://caroster.io

frontend/pages/e/[eventId].tsx (view raw)

  1import {useState, useReducer, useEffect} from 'react';
  2import {useTranslation} from 'react-i18next';
  3import Layout from '../../layouts/Default';
  4import Fab from '../../containers/Fab';
  5import CarColumns from '../../containers/CarColumns';
  6import NewCarDialog from '../../containers/NewCarDialog';
  7import AddToMyEventDialog from '../../containers/AddToMyEventDialog';
  8import EventBar from '../../containers/EventBar';
  9import useToastStore from '../../stores/useToastStore';
 10import {initializeApollo} from '../../lib/apolloClient';
 11import ErrorPage from '../_error';
 12import {
 13  useUpdateEventMutation,
 14  Event as EventType,
 15  useEventQuery,
 16  EventDocument,
 17} from '../../generated/graphql';
 18import useEventStore from '../../stores/useEventStore';
 19import Loading from '../../containers/Loading';
 20
 21interface Props {
 22  event: EventType;
 23  eventId: string;
 24}
 25
 26const EventPage = props => {
 27  const {event} = props;
 28  const {t} = useTranslation();
 29
 30  if (!event) return <ErrorPage statusCode={404} title={t`event.not_found`} />;
 31
 32  return <Event {...props} />;
 33};
 34
 35const Event = (props: Props) => {
 36  const {eventId} = props;
 37  const {t} = useTranslation();
 38  const addToast = useToastStore(s => s.addToast);
 39  const setEvent = useEventStore(s => s.setEvent);
 40  const eventUpdate = useEventStore(s => s.event);
 41  const setIsEditing = useEventStore(s => s.setIsEditing);
 42  const [updateEvent] = useUpdateEventMutation();
 43  const [isAddToMyEvent, setIsAddToMyEvent] = useState(false);
 44  const [openNewCar, toggleNewCar] = useReducer(i => !i, false);
 45  const {data: {event} = {}, loading} = useEventQuery({
 46    variables: {id: eventId},
 47  });
 48
 49  useEffect(() => {
 50    if (event) setEvent(event as EventType);
 51  }, [event]);
 52
 53  const onSave = async e => {
 54    try {
 55      const {id, ...data} = eventUpdate;
 56      delete data.__typename;
 57      delete data.cars;
 58      await updateEvent({variables: {id, eventUpdate: data}});
 59      setIsEditing(false);
 60    } catch (error) {
 61      console.error(error);
 62      addToast(t('event.errors.cant_update'));
 63    }
 64  };
 65
 66  const onShare = async () => {
 67    if (!event) return null;
 68    // If navigator as share capability
 69    if (!!navigator.share)
 70      return await navigator.share({
 71        title: `Caroster ${event.name}`,
 72        url: `${window.location.href}`,
 73      });
 74    // Else copy URL in clipboard
 75    else if (!!navigator.clipboard) {
 76      await navigator.clipboard.writeText(window.location.href);
 77      addToast(t('event.actions.copied'));
 78      return true;
 79    }
 80  };
 81
 82  if (!event) return <Loading />;
 83
 84  return (
 85    <Layout
 86      pageTitle={t('event.title', {title: event.name})}
 87      menuTitle={t('event.title', {title: event.name})}
 88      displayMenu={false}
 89    >
 90      <EventBar
 91        event={event}
 92        onAdd={setIsAddToMyEvent}
 93        onSave={onSave}
 94        onShare={onShare}
 95      />
 96      <CarColumns toggleNewCar={toggleNewCar} />
 97      <Fab onClick={toggleNewCar} open={openNewCar} aria-label="add-car" />
 98      <NewCarDialog open={openNewCar} toggle={toggleNewCar} />
 99      <AddToMyEventDialog
100        event={event}
101        open={isAddToMyEvent}
102        onClose={() => setIsAddToMyEvent(false)}
103      />
104    </Layout>
105  );
106};
107
108export async function getServerSideProps(ctx) {
109  const {eventId} = ctx.query;
110  const apolloClient = initializeApollo();
111  const {data = {}} = await apolloClient.query({
112    query: EventDocument,
113    variables: {id: eventId},
114  });
115  const {event} = data;
116  const {host = ''} = ctx.req.headers;
117
118  return {
119    props: {
120      event,
121      eventId,
122      metas: {
123        title: event?.name || '',
124        url: `https://${host}${ctx.resolvedUrl}`,
125      },
126    },
127  };
128}
129
130export default EventPage;